package com.harveyspace.aes.social;

import com.harveyspace.aes.core.utils.LogUtil;
import com.harveyspace.aes.social.exception.SocialException;
import com.harveyspace.aes.social.pojo.AccessTokenInfo;
import com.harveyspace.aes.social.pojo.SocialiteUserInfo;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.lang3.StringUtils;

/**
 * Oauth 授权
 * 
 * @Author <a href="harveyer@163.com">harvey</a>
 * @date 2018/2/9
 */
public abstract class Oauth {
    
    protected final LogUtil logger = LogUtil.newInstance(getClass());
    
    protected SocialConfig socialConfig;
    
    protected String AUTH_URL = "";
    
	/**
     * @param socialConfig 配置信息
     */
    public Oauth(SocialConfig socialConfig) {
        super();
        this.socialConfig = socialConfig;
    }
    
    /**
     * 构造授权的Url
     * 
     * @param state OAuth2.0标准协议建议，利用state参数来防止CSRF攻击。可存储于session或其他cache中
     * @return String 构造完成的url字符串
     */
    public String getAuthorizeUrl(String state) {
        Map<String, String> params = new HashMap<>();
        params.put("response_type", "code");
        params.put("client_id", socialConfig.getClientId());
        params.put("redirect_uri", socialConfig.getRedirectUri());
        if (StringUtils.isNoneEmpty(state)) {
            params.put("state", state);
        }
        return this.initParams(AUTH_URL, params);
    }

    public AccessTokenInfo getAccessToken(Map<String, String> code) throws SocialException {
        return null;
    }

    public AccessTokenInfo getAccessToken(String code) throws SocialException {
        return null;
    }

    public abstract SocialiteUserInfo getSocialUserInfo(AccessTokenInfo accessTokenInfo) throws SocialException;
	
	/**
     * 构造请求参数
     * 
     * @param url url地址
     * @param params 参数集合
     * @return String 构造完成的url
     */
	protected String initParams(String url, Map<String, String> params) {
        if (null == params || params.isEmpty()) {
            return url;
        }
        StringBuilder sb = new StringBuilder(url);
        if (!url.contains("?")) {
            sb.append("?");
        }
        sb.append(map2Url(params));
        return sb.toString();
    }
    
    /**
     * map构造url
     * 
     * @param paramToMap 参数集合
     * @return String 构造完成的url
     */
    protected String map2Url(Map<String, String> paramToMap) {
        if (null == paramToMap || paramToMap.isEmpty()) {
            return null;
        }
        StringBuffer url = new StringBuffer();
        boolean isfist = true;
        for (Entry<String, String> entry : paramToMap.entrySet()) {
            if (isfist) {
                isfist = false;
            } else {
                url.append("&");
            }
            url.append(entry.getKey()).append("=");
            String value = entry.getValue();
            if (StringUtils.isNoneEmpty(value)) {
                try {
                    value = URLEncoder.encode(value, "UTF-8");
                }catch (UnsupportedEncodingException e){
                    throw new RuntimeException(e);
                }
            }
            url.append(value);
        }
        return url.toString();
    }

    /**
     * 解析URL格式的参数
     *
     * @param param 参数
     * @return map
     */
    protected Map<String, String> parserUrlParams(String param) {

        String[] items = StringUtils.splitByWholeSeparatorPreserveAllTokens(param, "&");

        Map<String, String> responseMap = new HashMap<>();
        for(String item : items) {

            String data[] = StringUtils.splitByWholeSeparatorPreserveAllTokens(item, "=");

            responseMap.put(data[0], data[1]);
        }

        return responseMap;
    }

    public SocialConfig getSocialConfig() {
        return socialConfig;
    }

    public void setSocialConfig(SocialConfig socialConfig) {
        this.socialConfig = socialConfig;
    }

}
